/**
 * @file setting_date_time.c
 *
 */

/*********************
 *      INCLUDES
 *********************/
#include "lv_watch.h"

#if USE_LV_WATCH_SETTING_DATETIME != 0

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/*********************
 *      DEFINES
 *********************/

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/
static void setting_date_time_prepare_destory(lv_obj_t * activity_obj);
static void date_time_set_btn_action(lv_obj_t * btn, lv_event_t event);
static void cancel_btn_action(lv_obj_t * obj, lv_event_t event);
static void ok_btn_action(lv_obj_t * obj, lv_event_t event);
static lv_obj_t * date_time_opt_create(lv_obj_t * par);
static uint8_t isleapyear(uint32_t year);
static lv_obj_t * date_time_roller_create(lv_obj_t * par, uint8_t type, hal_rtc_t * date_time);
static void get_yearopt_from_year(uint16_t year, char * yearopt);
static void date_roller_action(lv_obj_t * roller, lv_event_t event);
static void time_roller_action(lv_obj_t * roller, lv_event_t event);
static lv_datetime_obj_ext_t * datetime_get_ext(void);
static void time_task(lv_anim_t * anim);
static void get_rtc_time(hal_rtc_t * time);
static void set_rtc_time(hal_rtc_t * time);
static void get_num_from_string(char * str, char * delimiters, hal_rtc_t * date_time);
static void get_optstr_from_num(uint8_t num, uint8_t num2, char * stropt, uint8_t type, uint8_t leapyear);
static uint8_t get_daycnt_from_month(uint8_t month, uint8_t leapyear);

/**********************
 *  STATIC VARIABLES
 **********************/

/**********************
 *      MACROS
 **********************/
#define  SETTING_TIME_MIN_YEAR         2017
#define  SETTING_TIME_MAX_YEAR         2037
#define  SETTING_TIME_YEAR_LOOP_CNT    (SETTING_TIME_MAX_YEAR - SETTING_TIME_MIN_YEAR + 1)
#define  SETTING_TIME_TIME_OUT         1000
#define  SETTING_TIME_STR_LENGTH       12

/**********************
 *   GLOBAL FUNCTIONS
***********************/
lv_obj_t  * setting_date_time_create(lv_obj_t * activity_obj)
{
    lv_obj_t * obj;
    hal_rtc_t time;
    char time_str[SETTING_TIME_STR_LENGTH];

    lv_watch_activity_ext_t activity_ext;
    memset(&activity_ext, 0, sizeof(lv_watch_activity_ext_t));
    activity_ext.actId = ACT_ID_SETTING_DATETIME;
    activity_ext.create = setting_date_time_create;
    activity_ext.prepare_destory = setting_date_time_prepare_destory;
    activity_obj = lv_watch_creat_activity_obj(&activity_ext);
    LV_ASSERT_MEM(activity_obj);
    if(NULL == activity_obj) {
        return NULL;
    }

    obj = lv_watch_obj_create(activity_obj);
    LV_ASSERT_MEM(obj);
    if(NULL == obj) {
        return NULL;
    }

    /*Allocate the object type specific extended data*/
    lv_datetime_obj_ext_t * ext = lv_obj_allocate_ext_attr(obj, sizeof(lv_datetime_obj_ext_t));
    LV_ASSERT_MEM(ext);
    if(ext == NULL) return NULL;

    memset(&time, 0, sizeof(hal_rtc_t));
    get_rtc_time(&time);

    lv_obj_t * cont = lv_cont_create(obj, NULL);
    lv_cont_set_layout(cont, LV_LAYOUT_COLUMN_MID);
    lv_obj_set_size(cont, LV_HOR_RES, LV_VER_RES);
    lv_obj_add_style(cont, LV_CONT_PART_MAIN, &lv_style_transp);
    lv_obj_set_style_local_pad_top(cont, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 2);
    lv_obj_set_style_local_pad_bottom(cont, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 2);
    lv_obj_set_style_local_pad_left(cont, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 2);
    lv_obj_set_style_local_pad_right(cont, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 2);
    lv_obj_set_style_local_pad_inner(cont, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 20);
    lv_obj_set_y(cont, LV_VER_RES / 25);
    lv_obj_set_click(cont, false);
    lv_watch_obj_add_element(cont);

    lv_obj_t * title = lv_label_create(cont, NULL);
    lv_label_set_text_id(title, WATCH_TEXT_ID_DATE_AND_TIME);
    lv_obj_add_style(title, LV_LABEL_PART_MAIN, &lv_watch_font20_gray);

    /*date*/
    lv_obj_t * btn_date = lv_btn_create(cont, NULL);
    lv_watch_set_free_num(btn_date, 1);

    lv_obj_add_style(btn_date, LV_BTN_PART_MAIN, &lv_style_transp_fit);
    lv_btn_set_fit2(btn_date, LV_FIT_NONE, LV_FIT_TIGHT);
    lv_btn_set_layout(btn_date, LV_LAYOUT_OFF);
    lv_obj_set_width(btn_date, LV_HOR_RES * 3 / 5);
    lv_obj_set_event_cb(btn_date, date_time_set_btn_action);
    lv_obj_add_protect(btn_date, LV_PROTECT_PRESS_LOST);
    lv_watch_obj_add_element(btn_date);

    lv_obj_t * cont_date = lv_cont_create(btn_date, NULL);
    lv_obj_add_style(cont_date, LV_OBJ_PART_MAIN, &lv_style_transp_fit);
    lv_obj_set_width(cont_date, lv_obj_get_width(btn_date));
    lv_btn_set_layout(cont_date, LV_LAYOUT_ROW_MID);
    lv_obj_align(cont_date, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 0);
    lv_cont_set_fit2(cont_date, LV_FIT_NONE, LV_FIT_TIGHT);
    lv_obj_set_click(cont_date, false);

    lv_obj_t * img_date = lv_img_create(cont_date, NULL);
    lv_img_set_src(img_date, ICON_DATE);
    lv_obj_set_pos(img_date, 0, 0);

    lv_obj_t * label_setdate = lv_label_create(cont_date, title);
    lv_label_set_text_id(label_setdate, WATCH_TEXT_ID_DATE_SETTING);

    ext->label_date = lv_label_create(btn_date, NULL);
    memset(time_str, 0, SETTING_TIME_STR_LENGTH);
    snprintf(time_str, SETTING_TIME_STR_LENGTH,  "%d-%02d-%02d", time.tm_year, time.tm_mon, time.tm_mday);
    lv_label_set_text(ext->label_date, time_str);
    lv_obj_add_style(ext->label_date, LV_LABEL_PART_MAIN, &lv_watch_font20);
    if(lv_obj_get_base_dir(cont_date) == LV_BIDI_DIR_RTL)
        lv_obj_align(ext->label_date, label_setdate, LV_ALIGN_OUT_BOTTOM_RIGHT, 0, 10);
    else
        lv_obj_align(ext->label_date, label_setdate, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 10);

    /*time*/
    lv_obj_t * btn_time = lv_btn_create(cont, btn_date);
    lv_watch_set_free_num(btn_time, 2);
    lv_watch_obj_add_element(btn_time);

    lv_obj_t * cont_time = lv_cont_create(btn_time, cont_date);
    lv_obj_set_width(cont_time, lv_obj_get_width(btn_time));
    lv_obj_t * img_time = lv_img_create(cont_time, NULL);
    lv_img_set_src(img_time, ICON_TIME);
    lv_obj_set_pos(img_time, 0, 0);

    lv_obj_t * label_settime = lv_label_create(cont_time, title);
    lv_label_set_text_id(label_settime, WATCH_TEXT_ID_TIME_SETTING);

    ext->label_time = lv_label_create(btn_time, ext->label_date);
    lv_obj_set_base_dir(ext->label_time, LV_BIDI_DIR_LTR);
    memset(time_str, 0, SETTING_TIME_STR_LENGTH);
    snprintf(time_str, SETTING_TIME_STR_LENGTH, "%02d:%02d:%02d", time.tm_hour, time.tm_min, time.tm_sec);
    lv_label_set_text(ext->label_time, time_str);
    if(lv_obj_get_base_dir(cont_time) == LV_BIDI_DIR_RTL)
        lv_obj_align(ext->label_time, label_settime, LV_ALIGN_OUT_BOTTOM_RIGHT, 0, 10);
    else
        lv_obj_align(ext->label_time, label_settime, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);

    /*uptate time*/
    lv_anim_t a;

    lv_anim_init(&a);
    lv_anim_set_var(&a, ext->label_time);
    lv_anim_set_time(&a, 1);
    lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);
    lv_anim_set_repeat_delay(&a, SETTING_TIME_TIME_OUT);       // update every 1s
    lv_anim_set_start_cb(&a, time_task);
    lv_anim_start(&a);

    return obj;
}

void setting_date_time_create_btn_action(lv_obj_t * btn, lv_event_t event)
{
    (void)btn;

    if(LV_EVENT_CLICKED != event) return;

    lv_watch_png_cache_all_free();

    lv_obj_t * obj = setting_date_time_create(NULL);
    LV_ASSERT_MEM(obj);
    if(obj == NULL) return;
}

void watch_modem_time_update_ind(MMI_Modem_Time_Info_t * TimeInfo)
{
    hal_rtc_t time;
    uint32_t seconds;

    memset(&time, 0, sizeof(hal_rtc_t));
    time.tm_sec = TimeInfo->tm_sec;
    time.tm_min = TimeInfo->tm_min;
    time.tm_hour = TimeInfo->tm_hour;
    time.tm_mday = TimeInfo->tm_mday;
    time.tm_mon = TimeInfo->tm_mon;
    time.tm_year = TimeInfo->tm_year;

    seconds = time_to_seconds(&time);
    seconds += TimeInfo->timezone * 15 * 60; // 1 offset means 15min
    seconds_to_time(seconds, &time);

    printf("%s %d, %d, %d, %d, %d, %d, %d\n", __FUNCTION__,
           time.tm_year, time.tm_mon,
           time.tm_mday, time.tm_hour,
           time.tm_min, time.tm_sec,
           TimeInfo->timezone);

    Hal_Mem_Free(TimeInfo);
    set_rtc_time(&time);
}

/**********************
 *   STATIC FUNCTIONS
 **********************/
static lv_datetime_obj_ext_t * datetime_get_ext(void)
{
    lv_obj_t * activity_obj = lv_watch_get_activity_obj(ACT_ID_SETTING_DATETIME);
    if(activity_obj == NULL) return NULL;

    lv_obj_t * watch_obj;
    lv_watch_get_child_obj(activity_obj, lv_watch_obj_signal, &watch_obj);
    if(watch_obj == NULL) return NULL;

    if(watch_obj) {
        lv_datetime_obj_ext_t  * ext = lv_obj_get_ext_attr(watch_obj);
        return ext;
    }
    return NULL;
}

static void setting_date_time_prepare_destory(lv_obj_t * activity_obj)
{
    lv_watch_png_cache_all_free();
}

static void time_task(lv_anim_t * anim)
{
    char new_str[12];
    hal_rtc_t date_time;

    memset(new_str, 0, 12);
    memset(&date_time, 0, sizeof(hal_rtc_t));

    get_rtc_time(&date_time);
    snprintf(new_str, 12, "%02d:%02d:%02d", date_time.tm_hour, date_time.tm_min, date_time.tm_sec);
    lv_label_set_text(anim->var, new_str);
    if(date_time.tm_hour == 0 && date_time.tm_min == 0 && date_time.tm_sec == 0) {
        lv_datetime_obj_ext_t * ext = datetime_get_ext();
        memset(new_str, 0, 12);
        snprintf(new_str, 12, "%d-%02d-%02d", date_time.tm_year, date_time.tm_mon, date_time.tm_mday);
        lv_label_set_text(ext->label_date, new_str);
    }


}

static void set_rtc_time(hal_rtc_t * time)
{
    Hal_Rtc_Settime(time);

    alarm_set_rtc_alarm();
}

static void get_rtc_time(hal_rtc_t * time)
{
    Hal_Rtc_Gettime(time);
}

static void date_time_set_btn_action(lv_obj_t * btn, lv_event_t event)
{
    lv_obj_t * label;
    char str[SETTING_TIME_STR_LENGTH];

    if(LV_EVENT_CLICKED != event) return;
    lv_obj_t * obj = lv_watch_obj_create(lv_watch_get_activity_obj(ACT_ID_SETTING_DATETIME));
    uint8_t type = (uint8_t)lv_obj_get_user_data(btn).user_num;
    hal_rtc_t date_time;
    memset(&date_time, 0, sizeof(hal_rtc_t));
    label = lv_obj_get_child(btn, NULL);
    memset(str, 0, SETTING_TIME_STR_LENGTH);
    strncpy(str, lv_label_get_text(label), SETTING_TIME_STR_LENGTH);

    if(type == 1) {
        get_num_from_string(str, "-", &date_time);
    } else if(type == 2) {
        get_num_from_string(str, ":", &date_time);
    }

    date_time_roller_create(obj, type, &date_time);
    date_time_opt_create(obj);
}

static lv_obj_t * date_time_roller_create(lv_obj_t * par, uint8_t type, hal_rtc_t * date_time)
{
    lv_obj_t * content;
    lv_obj_t * roller1_cont;
    lv_obj_t * roller2_cont;
    lv_obj_t * roller3_cont;
    lv_obj_t * roller1;
    lv_obj_t * roller2;
    lv_obj_t * roller3;
    lv_obj_t * label1;
    lv_obj_t * label2;

    uint8_t leapyear = 0;
    lv_datetime_obj_ext_t * ext = datetime_get_ext();
#if USE_LV_WATCH_ENGINEER_MODE!= 0
    lv_engineer_hardware_testing_obj_ext_t * hw_ext = NULL;
    if(ext == NULL) {
        hw_ext = hardware_testing_get_ext();
    }
#endif

    lv_obj_t * label = lv_label_create(par, NULL);
    if(type == 1)
        lv_label_set_text_id(label, WATCH_TEXT_ID_DATE_SETTING);
    else
        lv_label_set_text_id(label, WATCH_TEXT_ID_TIME_SETTING);
    lv_obj_add_style(label, LV_LABEL_PART_MAIN, &lv_watch_font20_gray);
    lv_label_set_long_mode(label, LV_LABEL_LONG_BREAK);
    lv_obj_set_height(label, 40);
    lv_obj_align(label, NULL, LV_ALIGN_IN_TOP_MID, 0, 10);

    content =  lv_cont_create(par, NULL);
    if(type == 2)
        lv_obj_set_base_dir(content, LV_BIDI_DIR_LTR);
    lv_obj_set_size(content, LV_HOR_RES, LV_VER_RES / 2);
    lv_obj_set_pos(content, 0, lv_obj_get_height(label));
    lv_cont_set_layout(content, LV_LAYOUT_ROW_MID);
    lv_obj_add_style(content, LV_CONT_PART_MAIN, &lv_style_transp);
    lv_obj_set_style_local_pad_top(content, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 2);
    lv_obj_set_style_local_pad_bottom(content, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 2);
    lv_obj_set_style_local_pad_left(content, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 10);
    lv_obj_set_style_local_pad_right(content, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 10);
    lv_obj_set_style_local_pad_inner(content, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5);
    lv_obj_align(content, label, LV_ALIGN_OUT_BOTTOM_MID, 0, 5);

    /*roller1 year or hour*/
    roller1_cont = lv_cont_create(content, NULL);
    lv_obj_set_size(roller1_cont, LV_HOR_RES / 4, LV_VER_RES / 2);
    lv_cont_set_layout(roller1_cont, LV_LAYOUT_OFF);
    lv_obj_add_style(roller1_cont, LV_CONT_PART_MAIN, &lv_watch_style_transp);

    roller1 = lv_roller_create(roller1_cont, NULL);
    ext->roller[0] = roller1;
    lv_obj_add_style(roller1, LV_ROLLER_PART_BG, &lv_watch_font20_gray);
    lv_obj_set_style_local_text_line_space(roller1, LV_ROLLER_PART_BG, LV_STATE_DEFAULT, 20);
    lv_obj_set_style_local_bg_opa(roller1, LV_ROLLER_PART_BG, LV_STATE_DEFAULT, LV_OPA_TRANSP);
    lv_obj_add_style(roller1, LV_ROLLER_PART_SELECTED, &lv_watch_font20_gray);
    lv_obj_set_style_local_text_line_space(roller1, LV_ROLLER_PART_SELECTED, LV_STATE_DEFAULT, 20);
    lv_obj_set_style_local_bg_opa(roller1, LV_ROLLER_PART_SELECTED, LV_STATE_DEFAULT, LV_OPA_TRANSP);
    lv_roller_set_visible_row_count(roller1, 3);

    /*label1 - or :*/
    label1 = lv_label_create(content, NULL);
    lv_obj_set_style_local_text_font(label1, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_THEME_WATCH_NIGHT_FONT_BIG);
    lv_obj_set_style_local_text_color(label1, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_ORANGE);

    /*roller2 month or minute*/
    roller2_cont = lv_cont_create(content, roller1_cont);
    roller2 = lv_roller_create(roller2_cont, NULL);
    ext->roller[1] = roller2;
    lv_obj_add_style(roller2, LV_ROLLER_PART_BG, &lv_watch_font20_gray);
    lv_obj_set_style_local_text_line_space(roller2, LV_ROLLER_PART_BG, LV_STATE_DEFAULT, 20);
    lv_obj_set_style_local_bg_opa(roller2, LV_ROLLER_PART_BG, LV_STATE_DEFAULT, LV_OPA_TRANSP);
    lv_obj_add_style(roller2, LV_ROLLER_PART_SELECTED, &lv_watch_font20_gray);
    lv_obj_set_style_local_text_line_space(roller2, LV_ROLLER_PART_SELECTED, LV_STATE_DEFAULT, 20);
    lv_obj_set_style_local_bg_opa(roller2, LV_ROLLER_PART_SELECTED, LV_STATE_DEFAULT, LV_OPA_TRANSP);
    lv_roller_set_visible_row_count(roller2, 3);

    /*label1 - or :*/
    label2 = lv_label_create(content, label1);

    /*roller3 day or second*/
    roller3_cont = lv_cont_create(content, roller1_cont);
    roller3 = lv_roller_create(roller3_cont, NULL);
    ext->roller[2] = roller3;
    lv_obj_add_style(roller3, LV_ROLLER_PART_BG, &lv_watch_font20_gray);
    lv_obj_set_style_local_text_line_space(roller3, LV_ROLLER_PART_BG, LV_STATE_DEFAULT, 20);
    lv_obj_set_style_local_bg_opa(roller3, LV_ROLLER_PART_BG, LV_STATE_DEFAULT, LV_OPA_TRANSP);
    lv_obj_add_style(roller3, LV_ROLLER_PART_SELECTED, &lv_watch_font20_gray);
    lv_obj_set_style_local_text_line_space(roller3, LV_ROLLER_PART_SELECTED, LV_STATE_DEFAULT, 20);
    lv_obj_set_style_local_bg_opa(roller3, LV_ROLLER_PART_SELECTED, LV_STATE_DEFAULT, LV_OPA_TRANSP);
    lv_roller_set_visible_row_count(roller3, 3);

    lv_watch_set_free_num(roller1, 1);
    lv_watch_set_free_num(roller2, 2);
    lv_watch_set_free_num(roller3, 3);

    /*set date*/
    if(type == 1) {
        char year_opt[80];
        char day_opt[40];
        char mon_opt[40];

        if(ext) {
            ext->leapyear = isleapyear(date_time->tm_year);
            leapyear = ext->leapyear;
        }
#if USE_LV_WATCH_ENGINEER_MODE!= 0
        else {
            hw_ext->leapyear = isleapyear(date_time->tm_year);
            leapyear = hw_ext->leapyear;
        }
#endif

        memset(day_opt, 0, 40);
        memset(mon_opt, 0, 40);
        memset(year_opt, 0, 80);

        get_yearopt_from_year(date_time->tm_year, year_opt);
        get_optstr_from_num(date_time->tm_mon, 0, mon_opt, 1, 0);
        get_optstr_from_num(date_time->tm_mday, date_time->tm_mon, day_opt, 4, leapyear);

        lv_roller_set_options(roller1, year_opt, LV_ROLLER_MODE_NORMAL);
        lv_obj_set_event_cb(roller1, date_roller_action);

        lv_roller_set_options(roller2, mon_opt, LV_ROLLER_MODE_NORMAL);
        lv_obj_set_event_cb(roller2, date_roller_action);

        lv_roller_set_options(roller3, day_opt, LV_ROLLER_MODE_NORMAL);
        lv_obj_set_event_cb(roller3, date_roller_action);

        lv_label_set_text(label1, "  -");
        lv_label_set_text(label2, "-");

        lv_watch_set_free_num(content, 1);
    } else if(type == 2) { /*set time*/
        char hour_opt[40];
        char min_opt[40];
        char sec_opt[40];
        memset(hour_opt, 0, 40);
        memset(min_opt, 0, 40);
        memset(sec_opt, 0, 40);

        get_optstr_from_num(date_time->tm_hour, 0, hour_opt, 2, 0);
        get_optstr_from_num(date_time->tm_min, 0, min_opt, 3, 0);
        get_optstr_from_num(date_time->tm_sec, 0, sec_opt, 3, 0);

        lv_roller_set_options(roller1, hour_opt, LV_ROLLER_MODE_NORMAL);
        lv_obj_set_event_cb(roller1,  time_roller_action);

        lv_roller_set_options(roller2, min_opt, LV_ROLLER_MODE_NORMAL);
        lv_obj_set_event_cb(roller2, time_roller_action);

        lv_roller_set_options(roller3, sec_opt, LV_ROLLER_MODE_NORMAL);
        lv_obj_set_event_cb(roller3, time_roller_action);

        lv_label_set_text(label1, ":");
        lv_label_set_text(label2, ":");

        lv_watch_set_free_num(content, 2);
    }

    char str[3] = "00";
    memset(ext->sel_str[0],0,6);
    memset(ext->sel_str[1],0,6);
    memset(ext->sel_str[2],0,6);
    strncpy(ext->sel_str[0],str,2);
    strncpy(ext->sel_str[1],str,2);
    strncpy(ext->sel_str[2],str,2);
    lv_roller_set_auto_fit(roller1, true);
    lv_roller_set_selected(roller1, 5, LV_ANIM_OFF);
    lv_watch_roller_set_sel_style(roller1, ext->sel_str[0]);

    lv_roller_set_auto_fit(roller2, true);
    lv_roller_set_selected(roller2, 5, LV_ANIM_OFF);
    lv_watch_roller_set_sel_style(roller2, ext->sel_str[1]);

    lv_roller_set_auto_fit(roller3, true);
    lv_roller_set_selected(roller3, 5, LV_ANIM_OFF);
    lv_watch_roller_set_sel_style(roller3, ext->sel_str[2]);

    return content;
}

static lv_obj_t * date_time_opt_create(lv_obj_t * par)
{
    lv_obj_t * content = lv_cont_create(par, NULL);
    lv_cont_set_fit2(content, LV_FIT_NONE, LV_FIT_TIGHT);
    lv_obj_set_width(content, LV_HOR_RES);
    lv_cont_set_layout(content, LV_LAYOUT_ROW_MID);
    LV_ASSERT_MEM(content);
    if(content == NULL) return NULL;
    lv_obj_set_click(content, true);
    lv_obj_align(content, par, LV_ALIGN_IN_BOTTOM_MID, 0, -LV_VER_RES / 12);
    lv_obj_add_style(content, LV_CONT_PART_MAIN, &lv_style_transp);
    lv_obj_set_style_local_pad_left(content, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 20);
    lv_obj_set_style_local_pad_right(content, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 20);
    lv_obj_set_style_local_pad_inner(content, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 70);

    lv_obj_t * btn;
    btn = lv_imgbtn_create(content, NULL);
    lv_imgbtn_set_src(btn, LV_BTN_STATE_RELEASED, ICON_CANCEL);
    lv_imgbtn_set_src(btn, LV_BTN_STATE_PRESSED, ICON_CANCEL);
    lv_obj_set_event_cb(btn, cancel_btn_action);

    btn = lv_imgbtn_create(content, NULL);
    lv_imgbtn_set_src(btn, LV_BTN_STATE_RELEASED, ICON_OK);
    lv_imgbtn_set_src(btn, LV_BTN_STATE_PRESSED, ICON_OK);
    lv_obj_set_event_cb(btn, ok_btn_action);

    return content;
}

static void date_roller_action(lv_obj_t * roller, lv_event_t event)
{
    char sel_str[6];
    char year_opt[80];
    char day_opt[40];
    char mon_opt[40];
    uint16_t year;
    uint8_t day;
    uint8_t new_day;
    uint8_t month;
    lv_obj_t * roller_day;
    lv_obj_t * roller_month;
    uint8_t leapyear = 0;
    lv_datetime_obj_ext_t * ext = datetime_get_ext();
#if USE_LV_WATCH_ENGINEER_MODE!= 0
    lv_engineer_hardware_testing_obj_ext_t * hw_ext = NULL;
    if(ext == NULL) {
        hw_ext = hardware_testing_get_ext();
    }
#endif

    if(LV_EVENT_VALUE_CHANGED != event) return;

    memset(sel_str, 0, 6);
    memset(year_opt, 0, 80);
    memset(day_opt, 0, 40);
    memset(mon_opt, 0, 40);

    lv_roller_get_selected_str(roller, sel_str, 6);
    //printf("date roller action sel_str = %s\n",sel_str);

    if(lv_obj_get_user_data(roller).user_num == 1) {
        year = atoi(sel_str);
        get_yearopt_from_year(year, year_opt);
        lv_roller_set_options(roller, year_opt, LV_ROLLER_MODE_NORMAL);
        lv_roller_set_selected(roller, 5, false);
        if(ext) ext->leapyear = isleapyear(year);
#if USE_LV_WATCH_ENGINEER_MODE!= 0
        else hw_ext->leapyear = isleapyear(year);
#endif

    } else if(lv_obj_get_user_data(roller).user_num == 2) {
        month = atoi(sel_str);
        get_optstr_from_num(month, 0, mon_opt, 1, 0);
        lv_roller_set_options(roller, mon_opt, LV_ROLLER_MODE_NORMAL);
        lv_roller_set_selected(roller, 5, false);
        roller_day = ext->roller[2];
        memset(sel_str, 0, 6);
        lv_roller_get_selected_str(roller_day, sel_str, 6);
        day = atoi(sel_str);

        if(ext)leapyear = ext->leapyear;
#if USE_LV_WATCH_ENGINEER_MODE!= 0
        else leapyear = hw_ext->leapyear;
#endif

        new_day = get_daycnt_from_month(month, leapyear);
        if(new_day < day) day = new_day;

        get_optstr_from_num(day, month, day_opt, 4, leapyear);
        lv_roller_set_options(roller_day, day_opt, LV_ROLLER_MODE_NORMAL);
        lv_roller_set_selected(roller_day, 5, false);

    } else if(lv_obj_get_user_data(roller).user_num == 3) {
        day = atoi(sel_str);
        roller_month = ext->roller[1];
        memset(sel_str, 0, 6);
        lv_roller_get_selected_str(roller_month, sel_str, 6);
        month = atoi(sel_str);
        if(ext)leapyear = ext->leapyear;
#if USE_LV_WATCH_ENGINEER_MODE!= 0
        else leapyear = hw_ext->leapyear;
#endif
        get_optstr_from_num(day, month, day_opt, 4, leapyear);
        lv_roller_set_options(roller, day_opt, LV_ROLLER_MODE_NORMAL);
        lv_roller_set_selected(roller, 5, false);
    }
}

static void time_roller_action(lv_obj_t * roller, lv_event_t event)
{
    char sel_str[4];
    char hour_opt[40];
    char min_opt[40];
    char sec_opt[40];
    uint8_t hour;
    uint8_t min;
    uint8_t sec;

    if(LV_EVENT_VALUE_CHANGED != event) return;

    memset(sel_str, 0, 4);
    memset(hour_opt, 0, 40);
    memset(min_opt, 0, 40);
    memset(sec_opt, 0, 40);

    lv_roller_get_selected_str(roller, sel_str, 4);

    if(lv_obj_get_user_data(roller).user_num == 1) {
        hour = atoi(sel_str);
        get_optstr_from_num(hour, 0, hour_opt, 2, 0);
        lv_roller_set_options(roller, hour_opt, LV_ROLLER_MODE_NORMAL);
        lv_roller_set_selected(roller, 5, false);

    } else if(lv_obj_get_user_data(roller).user_num == 2) {
        min = atoi(sel_str);
        get_optstr_from_num(min, 0, min_opt, 3, 0);
        lv_roller_set_options(roller, min_opt, LV_ROLLER_MODE_NORMAL);
        lv_roller_set_selected(roller, 5, false);

    } else if(lv_obj_get_user_data(roller).user_num == 3) {
        sec = atoi(sel_str);
        get_optstr_from_num(sec, 0, sec_opt, 3, 0);
        lv_roller_set_options(roller, sec_opt, LV_ROLLER_MODE_NORMAL);
        lv_roller_set_selected(roller, 5, false);
    }
}

static void cancel_btn_action(lv_obj_t * obj, lv_event_t event)
{
    if(LV_EVENT_CLICKED != event) return;
    lv_obj_t * par_obj = lv_obj_get_parent(lv_obj_get_parent(lv_obj_get_parent(obj)));
    lv_obj_del(par_obj);
}
static void setting_set_time_flg(void)
{
    // nv write
    uint8_t nvdata = 1;
    UI_NV_Write_Req(NV_SECTION_UI_SETTINGS, 5, 1, &nvdata);
}
static void ok_btn_action(lv_obj_t * obj, lv_event_t event)
{
    char sel_str[SETTING_TIME_STR_LENGTH];
    char sel_str1[6];
    char sel_str2[4];
    char sel_str3[4];
    hal_rtc_t date_time;

    if(LV_EVENT_CLICKED != event) return;
    lv_datetime_obj_ext_t * ext = datetime_get_ext();
    lv_obj_t * par = lv_obj_get_parent(lv_obj_get_parent(obj));
    lv_obj_t * roller_cont = lv_obj_get_child(par, lv_obj_get_parent(obj));
    lv_obj_t * roller1 = ext->roller[0];
    lv_obj_t * roller2 = ext->roller[1];
    lv_obj_t * roller3 = ext->roller[2];

    memset(sel_str, 0, SETTING_TIME_STR_LENGTH);
    memset(sel_str1, 0, 6);
    memset(sel_str2, 0, 4);
    memset(sel_str3, 0, 4);
    lv_roller_get_selected_str(roller1, sel_str1, 6);
    lv_roller_get_selected_str(roller2, sel_str2, 4);
    lv_roller_get_selected_str(roller3, sel_str3, 4);
    //printf("roller str = %s %s %s\n", sel_str1,sel_str2,sel_str3);
    if(lv_obj_get_user_data(roller_cont).user_num == 1) {
        snprintf(sel_str, SETTING_TIME_STR_LENGTH, "%s-%s-%s", sel_str1, sel_str2, sel_str3);
        lv_label_set_text(ext->label_date, sel_str);
    } else if(lv_obj_get_user_data(roller_cont).user_num == 2) {
        snprintf(sel_str, SETTING_TIME_STR_LENGTH, "%s:%s:%s", sel_str1, sel_str2, sel_str3);
        lv_label_set_text(ext->label_time, sel_str);
    }

    memset(&date_time, 0, sizeof(hal_rtc_t));
    memset(sel_str, 0, SETTING_TIME_STR_LENGTH);
    strncpy(sel_str, lv_label_get_text(ext->label_date), SETTING_TIME_STR_LENGTH);
    get_num_from_string(sel_str, "-", &date_time);

    memset(sel_str, 0, SETTING_TIME_STR_LENGTH);
    strncpy(sel_str, lv_label_get_text(ext->label_time), SETTING_TIME_STR_LENGTH);
    get_num_from_string(sel_str, ":", &date_time);
    set_rtc_time(&date_time);
    setting_set_time_flg();

    lv_obj_del(lv_obj_get_parent(par));
}

static void get_num_from_string(char * str, char * delimiters, hal_rtc_t * date_time)
{
    char * temp;
    uint8_t date = 0;
    if(strcmp(delimiters, "-") == 0) {
        date = 1;
    }

    temp = strtok(str, delimiters);
    if(temp) {
        if(date)
            date_time->tm_year = atoi(temp);
        else
            date_time->tm_hour = atoi(temp);
        temp = strtok(NULL, delimiters);
        if(temp) {
            if(date)
                date_time->tm_mon = atoi(temp);
            else
                date_time->tm_min = atoi(temp);
            temp = strtok(NULL, delimiters);
            if(temp) {
                if(date)
                    date_time->tm_mday = atoi(temp);
                else
                    date_time->tm_sec = atoi(temp);
            }
        }
    }
}

static void get_yearopt_from_year(uint16_t year, char * yearopt)
{
    uint16_t year_display[11];
    uint8_t  i, pos = 0;

    year = year < SETTING_TIME_MIN_YEAR ? SETTING_TIME_MIN_YEAR : year;
    year = year > SETTING_TIME_MAX_YEAR ? SETTING_TIME_MAX_YEAR : year;
    // Create year roller options
    year_display[0] = ((year - SETTING_TIME_MIN_YEAR + SETTING_TIME_YEAR_LOOP_CNT) - 5) % SETTING_TIME_YEAR_LOOP_CNT + SETTING_TIME_MIN_YEAR;
    year_display[1] = ((year - SETTING_TIME_MIN_YEAR + SETTING_TIME_YEAR_LOOP_CNT) - 4) % SETTING_TIME_YEAR_LOOP_CNT + SETTING_TIME_MIN_YEAR;
    year_display[2] = ((year - SETTING_TIME_MIN_YEAR + SETTING_TIME_YEAR_LOOP_CNT) - 3) % SETTING_TIME_YEAR_LOOP_CNT + SETTING_TIME_MIN_YEAR;
    year_display[3] = ((year - SETTING_TIME_MIN_YEAR + SETTING_TIME_YEAR_LOOP_CNT) - 2) % SETTING_TIME_YEAR_LOOP_CNT + SETTING_TIME_MIN_YEAR;
    year_display[4] = ((year - SETTING_TIME_MIN_YEAR + SETTING_TIME_YEAR_LOOP_CNT) - 1) % SETTING_TIME_YEAR_LOOP_CNT + SETTING_TIME_MIN_YEAR;
    year_display[5] = year;
    year_display[6] = (year + 1 - SETTING_TIME_MIN_YEAR) % SETTING_TIME_YEAR_LOOP_CNT + SETTING_TIME_MIN_YEAR;
    year_display[7] = (year + 2 - SETTING_TIME_MIN_YEAR) % SETTING_TIME_YEAR_LOOP_CNT + SETTING_TIME_MIN_YEAR;
    year_display[8] = (year + 3 - SETTING_TIME_MIN_YEAR) % SETTING_TIME_YEAR_LOOP_CNT + SETTING_TIME_MIN_YEAR;
    year_display[9] = (year + 4 - SETTING_TIME_MIN_YEAR) % SETTING_TIME_YEAR_LOOP_CNT + SETTING_TIME_MIN_YEAR;
    year_display[10] = (year + 5 - SETTING_TIME_MIN_YEAR) % SETTING_TIME_YEAR_LOOP_CNT + SETTING_TIME_MIN_YEAR;

    for(i = 0; i < 11; i++) {
        yearopt[pos++] = year_display[i] / 1000 + 0x30;
        yearopt[pos++] = (year_display[i] % 1000) / 100 + 0x30;
        yearopt[pos++] = (year_display[i] % 100) / 10 + 0x30;
        yearopt[pos++] = year_display[i] % 10 + 0x30;
        yearopt[pos++] = 0x0A;
    }
    yearopt [pos - 1] = 0;
}

static void get_optstr_from_num(uint8_t num, uint8_t num2, char * stropt, uint8_t type, uint8_t leapyear)
{
    uint8_t opt_display[11];
    uint8_t i, pos = 0;
    uint8_t min = 1;
    uint8_t max = 0;
    uint8_t count = 0;
    if(type == 1) { //month
        max = 12;
        count = 12;
    } else if(type == 2) { //hour
        max = 23;
        min = 0;
        count = 24;
    } else if(type == 3) { //min&sec
        min = 0;
        max = 59;
        count = 60;
    } else if(type == 4) { //day
        max = get_daycnt_from_month(num2, leapyear);
        count = max;

    }

    opt_display[0] = ((num - min + count) - 5) % count + min;
    opt_display[1] = ((num - min + count) - 4) % count + min;
    opt_display[2] = ((num - min + count) - 3) % count + min;
    opt_display[3] = ((num - min + count) - 2) % count + min;
    opt_display[4] = ((num - min + count) - 1) % count + min;
    opt_display[5] = num;
    opt_display[6] = (num + 1 - min) % count + min;
    opt_display[7] = (num + 2 - min) % count + min;
    opt_display[8] = (num + 3 - min) % count + min;
    opt_display[9] = (num + 4 - min) % count + min;
    opt_display[10] = (num + 5 - min) % count + min;

    for(i = 0; i < 11; i++) {
        stropt[pos++] = (opt_display[i] % 100) / 10 + 0x30;
        stropt[pos++] = opt_display[i] % 10 + 0x30;
        stropt[pos++] = 0x0A;
    }
    stropt [pos - 1] = 0;

}

static uint8_t get_daycnt_from_month(uint8_t month, uint8_t leapyear)
{
    uint8_t daycnt = 0;
    if(month == 2) {
        if(leapyear == 1) {
            daycnt = 29;
        } else {
            daycnt = 28;
        }

    } else if((month == 4) || (month == 6) || (month == 9) || (month == 11)) {
        daycnt = 30;
    } else {
        daycnt = 31;
    }

    return daycnt;
}

static uint8_t isleapyear(uint32_t year)
{
    uint8_t leapyearflag = 0;

    if(year % 400 == 0) {
        leapyearflag = 1;
    } else {
        if((year % 4 == 0) && (year % 100 != 0)) {
            leapyearflag = 1;
        }
    }
    return(leapyearflag);
}

#endif /*USE_LV_WATCH_SETTING_DATETIME*/
